import { Injectable, UnauthorizedException } from '@nestjs/common';
import { Repository } from 'typeorm';
import { LoginDto } from './dto/login.dto';
import { LoginResponseDto } from './dto/login-response.dto';
import { InjectRepository } from '@nestjs/typeorm';
import { JwtService } from '@nestjs/jwt';
import { JWT_CONFIG } from '../../config/jwt.config';
import { UserInfo } from 'src/types/response';
import { User } from '../users/entities/user.entity';

@Injectable()
export class LoginService {
  constructor(
    @InjectRepository(User)
    private userRepository: Repository<User>,
    private readonly jwtService: JwtService,
  ) { }


  async login(loginDto: LoginDto): Promise<LoginResponseDto<null>> {
    const { username, password } = loginDto;
    console.log(loginDto, 'loginDto')
    // 查找用户
    const user = await this.userRepository.findOne({
      where: { username },
      relations: ['roles'] // 这里必须加
    });

    // 用户不存在，注册用户信息
    if (!user) {
      const user = await this.userRepository.save({
        username,
        password, // 注意：实际应用中密码应加密存储
        roles: [
          {
            id: 1,
            code: 'test',
            roleName: '测试角色',
            remark: '系统测试',
            updateTime: '2025-08-28 16:29:45',
          }
        ] // 新用户默认测试角色
      });
      const roleIds = user.roles.map(item => item.code);
      // 生成token，使用配置的默认过期时间
      const accessToken = this.generateToken(user.id, user.username, roleIds, JWT_CONFIG.DEFAULT_EXPIRES_IN);

      const refreshToken = this.generateLongToken(user.id, user.username, roleIds)
      console.log(user, '新注册用户信息')
      return {
        code: 200,
        msg: '自动注册登录成功',
        data: {
          token: accessToken,
          refreshToken
        }
      };
    }

    // 验证密码
    if (user.password !== password) {
      throw new UnauthorizedException('用户名或密码错误');
    }
    const roleIds = user.roles.map(item => item.code);
    // 生成token，使用配置的默认过期时间
    const accessToken = this.generateToken(user.id, user.username, roleIds, JWT_CONFIG.DEFAULT_EXPIRES_IN);

    const refreshToken = this.generateLongToken(user.id, user.username, roleIds)

    return {
      code: 200,
      msg: '登录成功',
      data: {
        token: accessToken,
        refreshToken
      }
    };
  }

  getUserList() {
    return this.userRepository.find();
  }

  async getUserInfo(token: string): Promise<ResponseData<UserInfo>> {
    try {
      // 解码 token，获取 payload
      const payload = this.jwtService.verify(token);
      const user = await this.userRepository.findOne({
        where: { id: payload.userId },
        relations: ['roles', 'roles.menus']
      });

      if (!user) {
        return {
          code: 404,
          msg: '用户不存在',
        };
      }

      // 获取用户所有角色的菜单
      const allMenus: any[] = [];
      if (user.roles && user.roles.length > 0) {
        for (const role of user.roles) {
          if (role.menus && role.menus.length > 0) {
            allMenus.push(...role.menus);
          }
        }
      }

      // 去重，避免重复菜单
      const uniqueMenus = allMenus.filter((menu, index, self) =>
        index === self.findIndex(m => m.id === menu.id)
      );

      console.log(user.roles, uniqueMenus, '输出user信息')


      const menuList = uniqueMenus.filter(item => item.type !== 3) || [];
      const buttonList = uniqueMenus.filter(item => item.type === 3) || [];

      return {
        code: 200,
        msg: '获取用户信息成功',
        data: {
          checkUser: {
            ...user
          },
          list: menuList,
          buttons: buttonList.map(btn => btn.code)
        }
      };
    } catch (e) {
      return {
        code: 403,
        msg: 'token无效或已过期',
      };
    }
  }

  // 生成默认短期token
  private generateToken(userId: number, username: string, roleIds: string[], expiresIn: string = JWT_CONFIG.DEFAULT_EXPIRES_IN): string {
    // 使用 JWT 生成 token，设置有效时间
    const payload = { userId, username, roleIds };
    return this.jwtService.sign(payload, { expiresIn });
  }

  // 生成长期token（7天）
  private generateLongToken(userId: number, username: string, roleIds: string[]): string {
    return this.generateToken(userId, username, roleIds, JWT_CONFIG.EXPIRES_IN.LONG);
  }

  // 验证token的方法
  async validateToken(token: string): Promise<boolean> {
    try {
      // verify 会自动校验签名和过期
      this.jwtService.verify(token);
      return true;
    } catch (e) {
      // Token 过期或无效
      return false;
    }
  }

  // 刷新token的方法
  async refreshToken(refreshToken: string): Promise<LoginResponseDto<null>> {
    try {
      // 验证 refreshToken
      const payload = this.jwtService.verify(refreshToken);
      // 查找用户
      const user = await this.userRepository.findOne({
        where: { id: payload.userId },
        relations: ['roles', 'roles.menus']
      });
      if (!user) {
        return {
          code: 404,
          msg: '用户不存在',
        };
      }
      const roleIds = user.roles.map(item => item.code);
      // 生成新的 accessToken
      const accessToken = this.generateToken(user.id, user.username, roleIds, JWT_CONFIG.DEFAULT_EXPIRES_IN);
      return {
        code: 200,
        msg: '刷新token成功',
        data: {
          token: accessToken
        }
      };
    } catch (e) {
      return {
        code: 403,
        msg: 'refreshToken无效或已过期',
      };
    }
  }
}
